/*
 *               ____
 *              /\   \
 *             ___\   \___
 *            /\          \
 *            \ \___    ___\
 *        ____ \/__/\   \__/
 *       /\   \    \ \___\    klof  |  innovative web technology
 *      ___\   \___ \/___/
 *     /\          \          klib3/xml.js
 *     \ \___    ___\         HTML Element style manipulation
 *      \/__/\   \__/
 *          \ \___\           Copyright 2003-2006, klof
 *           \/___/           http://www.klof.net/k.lib3/
 *
 */


/* Create the master klib3 object if she doesn't exist */
if ( typeof klib3 != "object" )
	klib3 = new ( function(){ this._child = 0 } )();



klib3.xml = function( bAutoRedirectOnFail )
{
	this._version  = "1.0.0";
	this._redirect = typeof bAutoRedirectOnFail == "boolean" ? bAutoRedirectOnFail : false;
};
klib3.xml.prototype.init = function()
{
	if ( window.XMLHttpRequest )
		this._xml = new XMLHttpRequest();
	else if ( window.ActiveXObject )
		this._xml = new ActiveXObject( "Microsoft.XMLHTTP" );
	return typeof this._xml == "object";
};
klib3.xml.prototype.request = function( sURL, sMethod, bAsync, oData, sUsername, sPassword )
{
	if ( this.init() )
	{
		var sParam = null;

		if ( typeof sMethod != "string" )
			sMethod = "GET";
		else
			sMethod = sMethod.toUpperCase();

		if ( typeof bAsync != "boolean" )
			bAsync = true;
		if ( typeof oData == "object" )
		{
			sParam = "";
			for ( var p in oData )
				if ( typeof oData[ p ] != "object" )
					sParam += ( sParam != "" ? "&" : "" ) + p + "=" + escape( oData[ p ] );
		}

		if ( bAsync )
		{
			var oBackRef = this;
			this._xml.onreadystatechange = function(){ oBackRef.onReadyStateChange(); }
		}

		if ( sMethod == "GET" && typeof sParam == "string" && sParam != "" )
		{
			sURL  += "?" + sParam;
			sParam = null;
		}

		if ( this._xml.overrideMimeType )
			this._xml.overrideMimeType( "text/xml" );

		this._xml.open( sMethod, sURL, bAsync, sUsername, sPassword );

		if ( sMethod == "POST" && typeof sParam == "string" && sParam != "" )
		{
			this._xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this._xml.setRequestHeader("Content-length", sParam.length);
			this._xml.setRequestHeader("Connection", "close");
		}
		this._xml.send( sParam );

		if ( !bAsync )
			return this._xml.responseXML;
		else
			return true;
	}
	else if ( this._redirect )
	{
		document.location = sURL
	};
	return false;
};
klib3.xml.prototype.onReadyStateChange = function()
{
	if ( this._xml.readyState == 4 )
	{
		if ( this._xml.status == 200 )
		{
			if ( typeof this.$__onload == "function" )
				this.$__onload();
			if ( typeof this.onload == "function" )
				this.onload();
		}
		else
		{
			if ( typeof this.$__onerror == "function" )
				this.$__onerror( this._xml.status );
			if ( typeof this.onerror == "function" )
				this.onerror( this._xml.status, this._xml.statusText );
		}
	}
};
klib3.xml.prototype.get = function( sURL, bAsync, oData, sUsername, sPassword )
{
	return this.request( sURL, "GET", bAsync, oData, sUsername, sPassword );
};
klib3.xml.prototype.post = function( sURL, bAsync, oData, sUsername, sPassword )
{
	return this.request( sURL, "POST", bAsync, oData, sUsername, sPassword );
};
klib3.xml.prototype.getData = function( bText )
{
	if ( bText )
		return this._xml.responseText;
	else if ( !this._xml.responseXML.firstChild )
		this._xml.responseXML.loadXML( this._xml.responseText );
	return this._xml.responseXML;
};
klib3.xml.prototype.loadIntoElement = function( mElement, sURL, sMethod, oParamData, sUsername, sPassword )
{
	this.$__onload = function()
	{
		if ( typeof this._xml.responseXML != "object" && typeof this.onerror == "function" )
		{
			this.onerror( this._xml.status, this._xml.statusText );
			return false;
		}
		var oHTML = this.convertToHTML( this._xml.responseXML );
		if ( typeof oHTML == "object" && typeof this.$__element == "object" )
			this.$__element.appendChild( oHTML );
		delete this.$__element;
		delete this.$__onload;
		if ( typeof this.onload == "function" )
			this.onload();
	};
	this.$__element = typeof mElement != "object" ? document.getElementById( mElement ) : mElement;
	return this.request( sURL, sMethod, true, oParamData, sUsername, sPassword );
};
klib3.xml.prototype.getIntoElement = function( mElement, sURL, oParamData, sUsername, sPassword )
{
	this.loadIntoElement( mElement, sURL, "GET", oParamData, sUsername, sPassword );
};
klib3.xml.prototype.postIntoElement = function( mElement, sURL, oParamData, sUsername, sPassword )
{
	this.loadIntoElement( mElement, sURL, "POST", oParamData, sUsername, sPassword );
};
/*
 *  Function : convertToHTML
 *  Purpose  : retrieve a block of HTML DOM node from an XML DOM object
 *  Synopsis : domnode convertToHTML( xmlnode oXML [, string nodename ] );
 *  Note     : if string nodename is not specified, it will retreive a HTML node from wherever 
 *             node that has an xmlns attribute set or it will return the topmost HTML node. 
 *             If a xmlns attribute has been set and string nodename is provided it will return 
 *             the HTML DOM node from whoever comes first.
 */
klib3.xml.prototype.convertToHTML = function( oXML )
{
	var oNode = null;
	var oDOM  = null;

	if ( oXML.nodeType == 1 || oXML.nodeType == 9 ) // XML node OR XML document
	{
		var bXMLNS = false;
		if ( oXML.nodeType == 1 )
			if ( typeof oXML.getAttribute == "function" )
			{
				bXMLNS = oXML.getAttribute( "xmlns" ) != "";
			}
			else if ( typeof oXML.attributes == "object" ) // IE Doesn't support the getAttribute methode.. working around it
			{
				for ( var i = 0; i < oXML.attributes.length; ++i )
					if ( oXML.attributes[ i ].name.toLowerCase() == "xmlns" )
					{
						bXMLNS = true;
						break;
					}
			}

		var nOffset = oXML.nodeName.indexOf( ":" ) + 1;
		if ( oXML.nodeType == 1 && // are we handling a non-declaration non-text node?
			( nOffset > 0 || bXMLNS || // do we have a namespace?
				(
					arguments.length > 1 &&  // do we have additional arguments?
					( 
						( typeof arguments[ 1 ] == "boolean" && arguments[ 1 ] ) || // did we explicitly order to add this node?
						( typeof arguments[ 1 ] == "string" && arguments[ 1 ].toLowerCase() == oXML.nodeName.toLowerCase() ) // did we request to add this node because it's nodename matches the input?
					)
				)
			)
		)
		{
			var sNodeName = nOffset > 0 ? oXML.nodeName.substr( nOffset, oXML.nodeName.length - nOffset ) : oXML.nodeName;
			oDOM = document.createElement( sNodeName );
			for ( var i = 0; i < oXML.attributes.length; ++i )
			{
				if ( oXML.attributes[ i ].name == "class" )
					oDOM.className = oXML.attributes[ i ].value;
				else if ( oXML.attributes[ i ].name != "xmlns" )
					oDOM.setAttribute( oXML.attributes[ i ].name, oXML.attributes[ i ].value );
			}

			for ( var i = 0; i < oXML.childNodes.length; ++i )
				if ( ( name = oXML.childNodes[ i ].nodeName ) != null )
					if ( typeof ( oNode = arguments.callee( oXML.childNodes[ i ], true ) ) == "object" )
					{
						// until we manage to have IE append styles and scripts without parsing every style rule seperatly, 
						// we skip the contents for them (use external scripts and links, which is nicer anyway)
						if ( oDOM.nodeName.toLowerCase() != "style" && oDOM.nodeName.toLowerCase() != "script" )
							oDOM.appendChild( oNode );
					}
		}
		else // XML Document OR no namespace
		{
			for ( var i = 0; i < oXML.childNodes.length; ++i )
				if ( oXML.childNodes[ i ].nodeType == 1 )
					oDOM = arguments.callee( oXML.childNodes[ i ], arguments[ 1 ] );
		}
	}
	else if ( oXML.nodeType == 3 || oXML.nodeType == 4 ) // XML TextNode or XML CDATA Node
	{
		oDOM = document.createTextNode( oXML.nodeValue );
	}
	else if ( oXML.nodeType == 8 ) // XML Comment
	{
		oDOM = document.createComment( oXML.nodeValue );
	}
	return oDOM;
};

// construct the klib3.xml Object onto itself so we have access to it's members
klib3.xml = new klib3.xml;
